package com.carrental.finance.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.carrental.finance.dto.PaymentDTO;
import com.carrental.finance.entity.Payment;
import com.carrental.finance.mapper.PaymentMapper;
import com.carrental.finance.service.PaymentService;
import com.carrental.finance.vo.PaymentVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 支付服务实现类
 */
@Service
public class PaymentServiceImpl extends ServiceImpl<PaymentMapper, Payment> implements PaymentService {

    /**
     * 创建支付记录
     *
     * @param paymentDTO 支付DTO
     * @return 支付ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createPayment(PaymentDTO paymentDTO) {
        // 生成支付单号
        String paymentNo = generatePaymentNo();
        
        Payment payment = new Payment();
        BeanUtils.copyProperties(paymentDTO, payment);
        payment.setPaymentNo(paymentNo);
        payment.setStatus(1); // 默认状态为待支付
        payment.setCreateTime(LocalDateTime.now());
        payment.setUpdateTime(LocalDateTime.now());
        
        // 保存支付记录
        save(payment);
        
        return payment.getId();
    }

    /**
     * 根据ID获取支付详情
     *
     * @param id 支付ID
     * @return 支付VO
     */
    @Override
    public PaymentVO getPaymentById(Long id) {
        Payment payment = getById(id);
        if (payment == null) {
            return null;
        }
        
        return convertToVO(payment);
    }

    /**
     * 根据支付单号获取支付详情
     *
     * @param paymentNo 支付单号
     * @return 支付VO
     */
    @Override
    public PaymentVO getPaymentByPaymentNo(String paymentNo) {
        LambdaQueryWrapper<Payment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Payment::getPaymentNo, paymentNo);
        
        Payment payment = getOne(wrapper);
        if (payment == null) {
            return null;
        }
        
        return convertToVO(payment);
    }

    /**
     * 根据订单ID获取支付详情列表
     *
     * @param orderId 订单ID
     * @return 支付VO列表
     */
    @Override
    public Page<PaymentVO> getPaymentsByOrderId(Long orderId, Page<Payment> page) {
        LambdaQueryWrapper<Payment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Payment::getOrderId, orderId);
        wrapper.orderByDesc(Payment::getCreateTime);
        
        Page<Payment> paymentPage = page(page, wrapper);
        
        return convertToVOPage(paymentPage);
    }

    /**
     * 根据用户ID分页查询支付记录
     *
     * @param userId 用户ID
     * @param page   分页参数
     * @return 支付VO分页
     */
    @Override
    public Page<PaymentVO> pageUserPayments(Long userId, Page<Payment> page) {
        LambdaQueryWrapper<Payment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Payment::getUserId, userId);
        wrapper.orderByDesc(Payment::getCreateTime);
        
        Page<Payment> paymentPage = page(page, wrapper);
        
        return convertToVOPage(paymentPage);
    }

    /**
     * 分页查询支付记录
     *
     * @param page        分页参数
     * @param paymentNo   支付单号
     * @param orderNo     订单号
     * @param userId      用户ID
     * @param paymentType 支付类型
     * @param status      支付状态
     * @param startTime   开始时间
     * @param endTime     结束时间
     * @return 支付VO分页
     */
    @Override
    public Page<PaymentVO> pagePayments(Page<Payment> page, String paymentNo, String orderNo, Long userId, Integer paymentType, Integer status, String startTime, String endTime) {
        LambdaQueryWrapper<Payment> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotBlank(paymentNo), Payment::getPaymentNo, paymentNo);
        wrapper.like(StringUtils.isNotBlank(orderNo), Payment::getOrderNo, orderNo);
        wrapper.eq(userId != null, Payment::getUserId, userId);
        wrapper.eq(paymentType != null, Payment::getPaymentType, paymentType);
        wrapper.eq(status != null, Payment::getStatus, status);
        
        if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            LocalDateTime start = LocalDateTime.parse(startTime, formatter);
            LocalDateTime end = LocalDateTime.parse(endTime, formatter);
            wrapper.between(Payment::getCreateTime, start, end);
        }
        
        wrapper.orderByDesc(Payment::getCreateTime);
        
        Page<Payment> paymentPage = page(page, wrapper);
        
        return convertToVOPage(paymentPage);
    }

    /**
     * 处理支付回调
     *
     * @param paymentNo     支付单号
     * @param transactionId 交易流水号
     * @param status        支付状态
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean handlePaymentCallback(String paymentNo, String transactionId, Integer status) {
        LambdaQueryWrapper<Payment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Payment::getPaymentNo, paymentNo);
        
        Payment payment = getOne(wrapper);
        if (payment == null) {
            return false;
        }
        
        // 更新支付状态和交易流水号
        payment.setStatus(status);
        payment.setTransactionId(transactionId);
        if (status == 3) { // 支付成功
            payment.setPaymentTime(LocalDateTime.now());
        }
        payment.setUpdateTime(LocalDateTime.now());
        
        return updateById(payment);
    }

    /**
     * 取消支付
     *
     * @param id 支付ID
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelPayment(Long id) {
        Payment payment = getById(id);
        if (payment == null) {
            return false;
        }
        
        // 只有待支付和支付中的订单可以取消
        if (payment.getStatus() != 1 && payment.getStatus() != 2) {
            return false;
        }
        
        // 更新支付状态为支付失败
        payment.setStatus(4);
        payment.setUpdateTime(LocalDateTime.now());
        
        return updateById(payment);
    }

    /**
     * 生成支付单号
     */
    private String generatePaymentNo() {
        // 生成格式为：P + 当前时间（年月日时分秒）+ 6位随机数
        String timeStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String randomStr = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 6);
        return "P" + timeStr + randomStr;
    }

    /**
     * 转换支付实体为VO
     */
    private PaymentVO convertToVO(Payment payment) {
        if (payment == null) {
            return null;
        }
        
        PaymentVO vo = new PaymentVO();
        BeanUtils.copyProperties(payment, vo);
        
        // 设置支付类型名称
        vo.setPaymentTypeName(getPaymentTypeName(payment.getPaymentType()));
        
        // 设置支付方式名称
        vo.setPaymentMethodName(getPaymentMethodName(payment.getPaymentMethod()));
        
        // 设置支付状态名称
        vo.setStatusName(getStatusName(payment.getStatus()));
        
        // TODO: 调用用户服务获取用户信息
        
        return vo;
    }

    /**
     * 转换支付分页为VO分页
     */
    private Page<PaymentVO> convertToVOPage(Page<Payment> page) {
        Page<PaymentVO> voPage = new Page<>();
        voPage.setCurrent(page.getCurrent());
        voPage.setSize(page.getSize());
        voPage.setTotal(page.getTotal());
        
        List<PaymentVO> voList = page.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        
        voPage.setRecords(voList);
        return voPage;
    }

    /**
     * 获取支付类型名称
     */
    private String getPaymentTypeName(Integer paymentType) {
        if (paymentType == null) {
            return "";
        }
        
        switch (paymentType) {
            case 1:
                return "租金";
            case 2:
                return "押金";
            case 3:
                return "赔偿金";
            case 4:
                return "退款";
            default:
                return "未知类型";
        }
    }

    /**
     * 获取支付方式名称
     */
    private String getPaymentMethodName(Integer paymentMethod) {
        if (paymentMethod == null) {
            return "";
        }
        
        switch (paymentMethod) {
            case 1:
                return "支付宝";
            case 2:
                return "微信";
            case 3:
                return "银行卡";
            default:
                return "未知方式";
        }
    }

    /**
     * 获取支付状态名称
     */
    private String getStatusName(Integer status) {
        if (status == null) {
            return "";
        }
        
        switch (status) {
            case 1:
                return "待支付";
            case 2:
                return "支付中";
            case 3:
                return "支付成功";
            case 4:
                return "支付失败";
            case 5:
                return "已退款";
            default:
                return "未知状态";
        }
    }
} 